package com.framework.service.yhbservice.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.framework.dao.YHBDao.user.YhbUserOrderDao;
import com.framework.entity.aliPay.AliPayConfig;
import com.framework.entity.ter.TerTerminalInfo;
import com.framework.entity.tran.TranLogistics;
import com.framework.exception.RRException;
import com.framework.exception.menu.RespCode;
import com.framework.service.LogisticsService;
import com.framework.service.TranOrderService;
import com.framework.service.yhbservice.*;
import com.framework.utils.ali.AliPay;
import com.framework.utils.httpClient.HttpClientUtil;
import com.framework.utils.string.StringUtil;
import com.framework.validator.Assert;
import com.framework.yhbEntity.activiy.YhbActivityInfo;
import com.framework.yhbEntity.currentcount.YhbCurrentCount;
import com.framework.yhbEntity.ter.YhbGoodsInfo;
import com.framework.yhbEntity.user.YhbUser;
import com.framework.yhbEntity.user.YhbUserAddress;
import com.framework.yhbEntity.user.YhbUserOrder;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("yhbUserOrderService")
public class YhbUserOrderServiceImpl extends ServiceImpl<YhbUserOrderDao, YhbUserOrder> implements YhbUserOrderService {



    @Autowired
    private YhbTerminalService yhbTerminalService;
    @Autowired
    private YhbUserService yhbUserService;
    @Autowired
    private YhbAddreesService yhbAddreesService;
    @Autowired
    private YhbGoodsService yhbGoodsService;
    @Autowired
    private LogisticsService logisticsService;
    @Autowired
    private YhbCurrentCountService yhbCurrentCountService;
    @Autowired
    private TranOrderService tranOrderService;

    @Autowired
    private  YhbActivityInfoService yhbActivityInfoService;

    @Override
    public String addOrder(String token, Long goodsId, Integer goodsNumber, BigDecimal goodsPrice) {
        if (StringUtils.isBlank(token) ||
                goodsId == null ||
                goodsId == 0 ||
                goodsNumber == null ||
                goodsNumber == 0 ||
                goodsPrice == null) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        YhbUser user = yhbUserService.queryUserByToken(token);

        //查询代理商的默认收货

        YhbUserAddress address = yhbAddreesService.getDefaultAddreess(token);
        if (address == null) {
            throw new RRException(RespCode.NOT_DEFAULT_ADDRESS);
        }
        //查询商品，验证订单的金额
        YhbGoodsInfo goods = yhbGoodsService.queryGoodsById(goodsId);
        if (goods == null) {
            throw new RRException("9000", "未查询到商品信息");
        }
        Integer isShow = goods.getIsShow();
        if (isShow == 2) {
            throw new RRException("9000", "商品已经被下架");
        }
        Long deptId = user.getDeptId();

        if (!deptId.equals(goods.getDeptId())) {
            throw new RRException("9000", "此商品不属于当前登录人");
        }

        BigDecimal price = goods.getPrice();
        BigDecimal totalPrice = price.multiply(new BigDecimal(goodsNumber));
        int res = totalPrice.compareTo(goodsPrice);
        if (res == 1 || res == -1) {
            throw new RRException("9000", "订单价格不一致");
        }
        //添加预支付订单信息
        String orderNo = verifyOrderNo(StringUtil.getDateString(6));
        insertOrders(orderNo, goodsNumber, goodsPrice, user, address.getAddressId(), goodsId);
        return orderNo;
    }

    private String verifyOrderNo(String orderNo) {
        YhbUserOrder yhbUserOrder=new YhbUserOrder();
        yhbUserOrder.setOrderNo(orderNo);
        YhbUserOrder order = baseMapper.selectOne(yhbUserOrder);
        if(order!=null){
            orderNo=StringUtil.getDateString(6);
            verifyOrderNo(orderNo);
        }
        return orderNo;
    }

    @Override
    public void insertOrders(String orderNo, Integer goodsNumber, BigDecimal goodsPrice, YhbUser user, String addressId, Long goodsId) {
        YhbUserOrder orders = new YhbUserOrder();
        orders.setUserId(user.getUserId());
        orders.setByDate(new Date());
        orders.setCreateTime(new Date());
        orders.setGoodsId(goodsId);
        orders.setGoodsPrice(goodsPrice);
        orders.setGoodsNumber(goodsNumber);
        orders.setAddressId(addressId);
        orders.setOrderNo(orderNo);
        orders.setDeptId(user.getDeptId());
        orders.setPhone(user.getPhone());
        baseMapper.insert(orders);

    }

    @Override
    public List<YhbUserOrder> queryOrdersList(String token, String orderState, String payState) {
        YhbUser user = yhbUserService.queryUserByToken(token);
        List<YhbUserOrder> list = baseMapper.selectList(new EntityWrapper<YhbUserOrder>()
                .eq("user_id", user.getUserId())
                .eq("order_state", orderState)
                .eq("pay_state", payState)
        );
        return list;
    }

    @Override
    public Map<String, Object> queryLogistics(String token, String orderNo) {
        Map<String, Object> map = new HashedMap();
        if (StringUtils.isBlank(orderNo)) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        //查询订单
        YhbUserOrder order = queryOrdersByNo(orderNo);
        map.put("order", order);
        Long logisticsId = order.getLogisticsId();
        if (logisticsId != null) {
            //所属物流
            TranLogistics logistics = logisticsService.queryLogisticsById(logisticsId);
            String code = logistics.getCode();
            String logisticsNum = order.getLogisticsNum();
            map.put("logistics", logistics);
            //查询物流信息
            String res = HttpClientUtil.doGet("http://www.kuaidi100.com/query", "type=" + code + "&postid=" + logisticsNum);
            //物流明细
            map.put("logisticsInfo", res);
        }
        return map;
    }

    private YhbUserOrder queryOrdersByNo(String orderNo) {
        Assert.isBlank(orderNo, "订单号不能为空");
        YhbUserOrder orders = new YhbUserOrder();
        orders.setOrderNo(orderNo);
        return baseMapper.selectOne(orders);
    }

    @Override
    public void cancelOrders(String token, String orderNo) {
        if (StringUtils.isBlank(token) ||
                StringUtils.isBlank(orderNo)) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        YhbUser user = yhbUserService.queryUserByToken(token);
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        Assert.isNull(orders, "未查询到订单");
        String userId = orders.getUserId();
        if (!userId.equals(user.getUserId())) {
            throw new RRException("9000", "此订单不属于当前登录人");
        }
        //校验订单状态、支付状态
        String payState = orders.getPayState();
        String orderState = orders.getOrderState();
        if (StringUtils.equals(payState, "SUCCESS") || StringUtils.equals(payState, "TIME_OUT")) {
            throw new RRException("9000", "支付状态不正确，不可取消");
        }
        if (StringUtils.equals(orderState, "WAIT_SIGN") || StringUtils.equals(orderState, "SUCCESS")) {
            throw new RRException("9000", "订单状态不正确，不可取消");
        }
        baseMapper.update(orders, new EntityWrapper<YhbUserOrder>().eq("pay_state", "CANCEL"));

    }

    @Override
    public void signOrders(String token, String orderNo) {
        if (StringUtils.isBlank(token) ||
                StringUtils.isBlank(orderNo)) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        YhbUser user = yhbUserService.queryUserByToken(token);
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        Assert.isNull(orders, "未查询到订单");
        String userId = orders.getUserId();
        if (!userId.equals(user.getUserId())) {
            throw new RRException("9000", "此订单不属于当前登录人");
        }
        //校验订单状态、支付状态
        String payState = orders.getPayState();
        String orderState = orders.getOrderState();
        if (!StringUtils.equals(payState, "SUCCESS")) {
            throw new RRException("9000", "此订单还未支付");
        }
        if (!StringUtils.equals(orderState, "WAIT_SIGN")) {
            throw new RRException("9000", "订单状态不正确，签收失败");
        }
        //取消订单
        baseMapper.update(orders, new EntityWrapper<YhbUserOrder>().eq("order_state", "SUCCESS"));
    }

    @Override
    public Map<String, Object> queryOrderInfo(String token, String orderNo) {

        Map<String, Object> map = new HashMap<>();
        Assert.isBlank(orderNo, "订单号不能为空");
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        if(orders==null){
            throw new RRException("9000","未查询到订单");
        }
        Long goodsId = orders.getGoodsId();//商品id
        String addressId = orders.getAddressId();//地址id
        YhbUser user = yhbUserService.queryUserByToken(token);
        if(!user.getUserId().equals(orders.getUserId())){
            throw  new RRException("9000","该订单不属于你");
        }

        if (StringUtils.isNotBlank(addressId)) {
            YhbUserAddress address = yhbAddreesService.selectById(addressId);
            map.put("address", address);
        }else {
            map.put("address","");
        }
        YhbGoodsInfo goods = yhbGoodsService.selectById(goodsId);
        map.put("orders", orders);
        map.put("goods", goods);
        return map;
    }

    @Override
    public void successPayState(String orderNo, String aliPayType) {
        Integer count = baseMapper.successPayState(orderNo);
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        if (count.intValue() > 0) {
            //添加账户流水日志
            YhbCurrentCount account=new YhbCurrentCount();
            account.setIncome(2);
            account.setIncomeType(1);
            account.setCreateDate(new Date());
            account.setRelationId(String.valueOf(orders.getYhbOrderId()));
            account.setAmount(orders.getGoodsPrice());
            account.setIsActivity(orders.getActivityFlag().intValue());
            String accountId=StringUtil.getDateString(5);
            account.setUserId(orders.getUserId());

            account.setAccountId(accountId);

            yhbCurrentCountService.insert(account);

        }
    }

    @Override
    public String pay(String token, String body, String subject, String orderNo, BigDecimal totalAmount, Integer payType, String password) {
        if (StringUtils.isBlank(token) ||
                StringUtils.isBlank(body) ||
                StringUtils.isBlank(subject) ||
                StringUtils.isBlank(orderNo) ||
                totalAmount == null) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        if (payType == 1) {
            throw new RRException("9000", "余额支付暂未开放");
        }

        YhbUser user = yhbUserService.queryUserByToken(token);
        String agId = user.getUserId();
        //渠道id
        Long deptId = user.getDeptId();
        //查询渠道支付宝参数信息
        AliPayConfig aliPayConfig = queryAliPayConfig(deptId);
        if (aliPayConfig == null) {
            throw new RRException("9000", "未查询到设置的支付宝参数");
        }
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        Assert.isBlank(orderNo, "未查询到订单");
        BigDecimal goodsPrice = orders.getGoodsPrice();
        String userId = orders.getUserId();
        if (!userId.equals(agId)) {
            throw new RRException("9000", "此订单不属于当前登录人");
        }
        //校验订单状态、支付状态
        String payState = orders.getPayState();
        if (!StringUtils.equals(payState, "PENDING")) {
            throw new RRException("9000", "支付状态不正确");
        }
        if (totalAmount.compareTo(goodsPrice) == 1 || totalAmount.compareTo(goodsPrice) == -1) {
            throw new RRException("9000", "支付金额不正确");
        }
        String orderString = "";
        //支付方式 1：余额支付  2：支付宝
        switch (payType) { //防止以后出现多种支付方式
            case 1:
                //查询账户余额 校验支付密码

                String takePassword = user.getTradePassword();
                if (!StringUtils.equals(takePassword, password)) {
                    throw new RRException("9000", "支付密码错误");
                }
                BigDecimal availableAmount = user.getAvailableAmount();//可提余额
                if (availableAmount.compareTo(totalAmount) == -1) {
                    throw new RRException("9000", "可用余额不足，支付失败");
                }
                //扣除支付的金额
                yhbUserService.reduceBalance(agId, totalAmount);
                //修改订单状态
                successPayState(orderNo, AliPay.ANT_TYPE);
                //添加订单流水

                break;
            case 2:
                Map<String, Object> map = new HashMap<>();
                map.put("body", body);
                map.put("subject", subject);
                map.put("order_no", orderNo);
                map.put("amount", totalAmount);

                try {
                    orderString = AliPay.Pay(map, aliPayConfig);
                } catch (Exception e) {
                    throw new RRException("9000", "支付失败，" + e.getMessage());
                }
                if (StringUtils.isBlank(orderString)) {
                    throw new RRException("9000", "启用支付宝接口失败");
                }
                break;
            default:
                throw new RRException("9000", "支付类型错误");
        }
        return orderString;
    }

    @Override
    public String addOrderByphone(String phone, Long goodsId, Integer goodsNumber, BigDecimal goodsPrice) {
        if (
                goodsId == null ||
                goodsId == 0 ||
                goodsNumber == null ||
                goodsNumber == 0 ||
                goodsPrice == null) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }


        //查询代理商的默认收货

        YhbUserAddress address = yhbAddreesService.queryAddressByPhone(phone);
        if(address==null){
            throw new RRException(RespCode.NOT_DEFAULT_ADDRESS);
        }
        //查询商品，验证订单的金额
        YhbGoodsInfo goods = yhbGoodsService.queryGoodsById(goodsId);
        if (goods == null) {
            throw new RRException("9000", "未查询到商品信息");
        }
        Integer isShow = goods.getIsShow();
        if (isShow == 2) {
            throw new RRException("9000", "商品已经被下架");
        }



        BigDecimal price = goods.getPrice();
        BigDecimal totalPrice = price.multiply(new BigDecimal(goodsNumber));
        int res = totalPrice.compareTo(goodsPrice);
        if (res == 1 || res == -1) {
            throw new RRException("9000", "订单价格不一致");
        }
        //添加预支付订单信息
        String orderNo = StringUtil.getDateString(6);
        insertOrders(orderNo, goodsNumber, goodsPrice, phone, address.getAddressId(), goodsId,goods.getDeptId());
        return orderNo;
    }

    private AliPayConfig queryAliPayConfig(Long deptId) {
        return tranOrderService.queryAliPayConfig(deptId);
    }

    @Override
    public void insertOrders(String orderNo, Integer goodsNumber, BigDecimal goodsPrice, String phone, String addressId, Long goodsId,Long deptId) {
        YhbUserOrder orders = new YhbUserOrder();

        orders.setByDate(new Date());
        orders.setCreateTime(new Date());
        orders.setGoodsId(goodsId);
        orders.setGoodsPrice(goodsPrice);
        orders.setGoodsNumber(goodsNumber);
        orders.setAddressId(addressId);
        orders.setOrderNo(orderNo);
        orders.setDeptId(deptId);
        orders.setPhone(phone);
        baseMapper.insert(orders);

    }

    @Override
    public Map<String, Object> queryOrderInfoByPhone(String phone, String orderNo) {
        Map<String, Object> map = new HashMap<>();
        Assert.isBlank(orderNo, "订单号不能为空");
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        if(orders==null){
            throw new RRException("9000","未查询到订单");
        }
        Long goodsId = orders.getGoodsId();//商品id
        String addressId = orders.getAddressId();//地址id
        if(!phone.equals(orders.getPhone())){
            throw new RRException("9000","该订单不属于你");
        }

        if (StringUtils.isNotBlank(addressId)) {
            YhbUserAddress address = yhbAddreesService.selectById(addressId);
            map.put("address", address);
        }else {
            map.put("address","");
        }
        //TerGoods goods = goodsService.queryGoodsById(goodsId);
        YhbGoodsInfo goods = yhbGoodsService.selectById(goodsId);
        map.put("orders", orders);
        map.put("goods", goods);
        return map;
    }

    @Override
    public String payByPhone(Long deptId, String body, String subject, String orderNo, BigDecimal totalAmount, Integer payType, String phone) {
        if (StringUtils.isBlank(phone) ||
                StringUtils.isBlank(body) ||
                StringUtils.isBlank(subject) ||
                StringUtils.isBlank(orderNo) ||
                totalAmount == null) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        if (payType == 1) {
            throw new RRException("9000", "余额支付暂未开放");
        }

        //查询渠道支付宝参数信息
        AliPayConfig aliPayConfig = queryAliPayConfig(deptId);
        if (aliPayConfig == null) {
            throw new RRException("9000", "未查询到设置的支付宝参数");
        }
        YhbUserOrder orders = queryOrdersByNo(orderNo);
        Assert.isBlank(orderNo, "未查询到订单");
        BigDecimal goodsPrice = orders.getGoodsPrice();
        if(!phone.equals(orders.getPhone())){
            throw new RRException("9000","该订单不属于你");
        }
        //校验订单状态、支付状态
        String payState = orders.getPayState();
        if (!StringUtils.equals(payState, "PENDING")) {
            throw new RRException("9000", "支付状态不正确");
        }
        if (totalAmount.compareTo(goodsPrice) == 1 || totalAmount.compareTo(goodsPrice) == -1) {
            throw new RRException("9000", "支付金额不正确");
        }
        String orderString = "";
        //支付方式 1：余额支付  2：支付宝
        switch (payType) { //防止以后出现多种支付方式
            case 1:

                throw new RRException("9000","错误的支付方式");

            case 2:
                Map<String, Object> map = new HashMap<>();
                map.put("body", body);
                map.put("subject", subject);
                map.put("order_no", orderNo);
                map.put("amount", totalAmount);

                try {
                    orderString = AliPay.Pay(map, aliPayConfig);
                } catch (Exception e) {
                    throw new RRException("9000", "支付失败，" + e.getMessage());
                }
                if (StringUtils.isBlank(orderString)) {
                    throw new RRException("9000", "启用支付宝接口失败");
                }
                break;
            default:
                throw new RRException("9000", "支付类型错误");
        }
        return orderString;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateOrdersAddress(String orderNo, String addressId, String token) {
        YhbUser user = yhbUserService.queryUserByToken(token);

        YhbUserOrder order = queryOrderByOrderNo(orderNo);

        if(!user.getUserId().equals(order.getUserId())){
            throw new RRException("9000","该订单不属于你");
        }

        if(order==null){
            throw new RRException("9000","未查询到订单");
        }
        order.setAddressId(addressId);
        return updateById(order);
    }


    @Override
    public YhbUserOrder queryOrderByOrderNo(String orderNo){
        YhbUserOrder yhbUserOrder=new YhbUserOrder();
        yhbUserOrder.setOrderNo(orderNo);
        return baseMapper.selectOne(yhbUserOrder);
    }

    @Override
    public void addOrder(String userId, String sn, Integer activityId,String orderNo,BigDecimal payAmount) {
        Assert.isBlank(userId,"用户id不能为空");

        Assert.isBlank(sn,"sn不能为空");

        TerTerminalInfo terminalInfo = yhbTerminalService.queryTerminalInfoBySn(sn);

        Assert.isNull(terminalInfo,"未查到该机具");

        Assert.isNull(orderNo,"订单号不能为空");

        YhbUser yhbUser = yhbUserService.queryUserByUserId(userId);

        YhbActivityInfo yhbActivityInfo = yhbActivityInfoService.selectById(activityId);

        if(payAmount.compareTo(yhbActivityInfo.getPayAmount())!=0){
            throw new RRException("9000","支付金额不正确");
        }

        YhbUserAddress address = yhbAddreesService.queryAddressByPhone(yhbUser.getPhone());

        YhbUserOrder yhbUserOrder=new YhbUserOrder();

        yhbUserOrder.setAddressId(address!=null?address.getAddressId():null);
        yhbUserOrder.setOrderNo(orderNo);
        yhbUserOrder.setPhone(yhbUser.getPhone());
        yhbUserOrder.setPayState("pending");
        yhbUserOrder.setUserId(userId);
        yhbUserOrder.setByDate(new Date());
        yhbUserOrder.setCreateTime(new Date());
        yhbUserOrder.setGoodsPrice(yhbActivityInfo.getPayAmount());
        yhbUserOrder.setPayType("web");
        yhbUserOrder.setDeptId(yhbUser.getDeptId());
        yhbUserOrder.setActivityFlag(1);
        yhbUserOrder.setSn(sn);
        yhbUserOrder.setGoodsId(activityId.longValue());

        insert(yhbUserOrder);

    }
}
